package com.google.code.mochaccino.framework.hibernate.provider.configuration;
/*
 * Copyright 2012 Claude Houle claude.houle@gmail.com
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

import com.google.common.base.Preconditions;
import java.sql.Connection;
import java.sql.Driver;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.Properties;
import org.hibernate.cfg.Environment;
import org.hibernate.service.jdbc.connections.internal.DriverManagerConnectionProviderImpl;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/** Session Factory for pure JDBC operation. */
public class ConfigurationProviderDriverManaged extends ConfigurationProvider {
	/** Logger */
	private static final Logger logger = LoggerFactory.getLogger( ConfigurationProviderDriverManaged.class );

	/** JDBC Driver Class */
	private Class<? extends Driver> driverClass = null;

	/** Password */
	private String password = null;

	/** JDBC URL */
	private String url = null;

	/** Username */
	private String username = null;

	@Override
	protected void configure( Properties p ) {
		super.configure( p );
		p.put( Environment.CONNECTION_PROVIDER, DriverManagerConnectionProviderImpl.class.getName() );
		p.put( Environment.USER, Preconditions.checkNotNull( username ) );
		p.put( Environment.PASS, Preconditions.checkNotNull( password ) );
		p.put( Environment.URL, Preconditions.checkNotNull( url ) );
		p.put( Environment.DRIVER, Preconditions.checkNotNull( driverClass ).getName() );
	}

	public void createSchema() throws SQLException {
		try {
			String[] script = get().generateSchemaCreationScript( super.getDialect().newInstance() );
			execScript( script );
		} catch ( InstantiationException e ) {
			throw new SQLException( e );
		} catch ( IllegalAccessException e ) {
			throw new SQLException( e );
		}
	}

	private void execScript( String[] scripts ) throws SQLException {
		Connection conn = null;
		Statement stmt = null;
		try {
			conn = getConnection();
			stmt = conn.createStatement();
			for ( String s : scripts ) {
				stmt.execute( s );
			}
		} finally {
			closeQuietly( stmt );
			closeQuietly( conn );
		}
	}

	private void closeQuietly( Connection conn ) {
		if ( conn != null ) {
			try {
				conn.close();
			} catch ( SQLException e ) {
				logger.error( e.getMessage(), e );
			}
		}
	}

	private void closeQuietly( Statement conn ) {
		if ( conn != null ) {
			try {
				conn.close();
			} catch ( SQLException e ) {
				logger.error( e.getMessage(), e );
			}
		}
	}

	private Connection getConnection() throws SQLException {
		return DriverManager.getConnection( url, username, password );
	}

	public void dropSchema() throws SQLException {
		try {
			String[] script = get().generateDropSchemaScript( super.getDialect().newInstance() );
			execScript( script );
		} catch ( InstantiationException e ) {
			throw new SQLException( e );
		} catch ( IllegalAccessException e ) {
			throw new SQLException( e );
		}
	}

	public void setDriverClass( Class<? extends Driver> driverClass ) {
		this.driverClass = driverClass;
	}

	public void setPassword( String password ) {
		this.password = password;
	}

	public void setUrl( String url ) {
		this.url = url;
	}

	public void setUsername( String username ) {
		this.username = username;
	}
}
